import json
import logging
import time

import requests

from const import ADDR

logger = logging.getLogger()


def get_sender_id(msg: dict):
    """
    取得发送者ID
    :param msg: 消息详情
    :return: 发送者ID
    """
    if not issubclass(msg.__class__, dict):
        raise ValueError("msg must be dict or subclass of dict!")
    if "sender" not in msg:
        raise KeyError("no sender in " + json.dumps(msg))
    if "id" not in msg["sender"]:
        raise KeyError("no id in sender" + json.dumps(msg))
    return msg['sender']["id"]


def get_group_id(msg: dict):
    """
    取得群ID
    :param msg: 消息详情
    :return: 群ID
    """
    if not issubclass(msg.__class__, dict):
        raise ValueError("msg must be dict or subclass of dict!")
    if "sender" not in msg:
        raise KeyError("no sender in " + json.dumps(msg))
    if "group" not in msg["sender"]:
        raise KeyError("no group in sender" + json.dumps(msg))
    if "id" not in msg["sender"]["group"]:
        raise KeyError("no id in sender" + json.dumps(msg))

    return msg['sender']['group']["id"]


# 取得数据包
def Get_data():
    data_file = open(r'../cfg.json', 'r', encoding='utf-8-sig')
    data = data_file.read()
    data = json.loads(data)
    return data


# 取得缓存的事件
def Get_Meesage():
    time.sleep(0.5)
    try:
        tempfile = open(r'messagetemp.sim', 'r', encoding='utf-8')
    except:
        return 0
    try:
        Message = eval(tempfile.read())
    except:
        tempfile.close()
        return 0
    tempfile.close()
    return Message


def _session_bind(addr: str, session: str, qq: str) -> dict:
    """
    会话绑定
    :param addr: 服务地址
    :param session: 会话编号
    :param qq: 机器人qq
    :return: 绑定结果
    """
    url = f'http://{addr}/bind'
    data_in = dict(sessionKey=session, qq=qq)
    res = requests.post(url, json=data_in)
    res = json.loads(res.text)
    return res


def get_session(cfg: dict, mode: int = 0) -> str:
    """
    得到 session
    :param cfg: 配置
    :param mode: 模式
    :return: session
    """
    verify_key = cfg['verifyKey']
    qq = cfg['qq']
    url = f'http://{ADDR}/verify'
    data_in = dict(verifyKey=verify_key)
    res = requests.post(url, json=data_in).json()
    if res["code"] != 0:
        raise RuntimeError("验证失败，详情请看: "
                           "https://docs.mirai.mamoe.net/mirai-api-http/api/API.html#%E7%8A%B6%E6%80%81%E7%A0%81")
    session = res['session']
    bind_res = _session_bind(ADDR, session, qq)
    code = bind_res['code']
    if code != 0:
        raise RuntimeError("创建会话失败！ response: %s" % bind_res)
    elif mode == 0:
        cfg.update(session=session)
        return session
    elif mode != 0:
        return session


def fetch_messages(session: str, count=100) -> list:
    """
    接受消息
    :param session: session code.
    :param count: max number of msg to fetch one times.
    :return: 消息列表
    """
    url = f"http://{ADDR}/fetchMessage?sessionKey={session}&count={count}"
    res = requests.get(url)
    res.raise_for_status()
    res = json.loads(res.text)
    logger.info("Fetch Msg: %s", res)
    return res['data']


# 发送消息(target_type:1-群,2-私聊,3-临时会话;message_type:1-文字,2-图片;path:传入不为0的int值可发送本地图片，默认为url)
##target_type为3，传入的target应当为一个字典dict，格式:{'qq':'123','group':'123'}
# 返回值为本次发送的消息id
def Send_Message(data, target, target_type, message, message_type, path=0):
    host = data['host']
    session = data['session']
    if target_type == 1 and message_type == 1:
        # logger.info('1')
        url = 'http://' + host + '/sendGroupMessage'
        messageinfo = []
        messagechain = dict(type='Plain', text=message)
        messageinfo.append(messagechain.copy())
    elif target_type == 2 and message_type == 1:
        # logger.info('2')
        url = 'http://' + host + '/sendFriendMessage'
        messageinfo = []
        messagechain = dict(type='Plain', text=message)
        messageinfo.append(messagechain.copy())
    elif target_type == 1 and message_type == 2:
        # logger.info('3')
        url = 'http://' + host + '/sendGroupMessage'
        messageinfo = []
        if path == 0:
            messagechain = dict(type='Image', url=message)
            messageinfo.append(messagechain.copy())
        elif path != 0:
            messagechain = dict(type='Image', path=message)
            messageinfo.append(messagechain.copy())
    elif target_type == 2 and message_type == 2:
        # logger.info('4')
        url = 'http://' + host + '/sendFriendMessage'
        messageinfo = []
        if path == 0:
            messagechain = dict(type='Image', url=message)
            messageinfo.append(messagechain.copy())
        elif path != 0:
            messagechain = dict(type='Image', path=message)
            messageinfo.append(messagechain.copy())
    elif target_type == 3 and message_type == 1:
        # logger.info('5')
        url = 'http://' + host + '/sendTempMessage'
        messageinfo = []
        messagechain = dict(type='Plain', text=message)
        messageinfo.append(messagechain.copy())
    elif target_type == 3 and message_type == 2:
        # logger.info('6')
        url = 'http://' + host + '/sendTempMessage'
        messageinfo = []
        if path == 0:
            messagechain = dict(type='Image', url=message)
            messageinfo.append(messagechain.copy())
        elif path != 0:
            messagechain = dict(type='Image', path=message)
            messageinfo.append(messagechain.copy())
    else:
        return 0
    if target_type == 3:
        data_in = dict(sessionKey=session, messageChain=messageinfo)
        data_in.update(target)
    else:
        data_in = dict(sessionKey=session, target=target, messageChain=messageinfo)
    res = requests.request('post', url, json=data_in)
    res = json.loads(res.text)
    if res['code'] == 0:
        return res['messageId']


# 若了解mah的消息链后，可以用此函数发送消息链
# 返回值为本次发送的消息id
def Send_Message_Chain(data, target, target_type, messagechain):
    host = data['host']
    session = data['session']
    if target_type == 1:
        url = 'http://' + host + '/sendGroupMessage'
    elif target_type == 2:
        url = 'http://' + host + '/sendFriendMessage'
    elif target_type == 3:
        url = 'http://' + host + '/sendTempMessage'
    else:
        return 0
    if target_type == 3:
        data_in = dict(sessionKey=session, messageChain=messagechain)
        data_in.update(target)
    else:
        data_in = dict(sessionKey=session, target=target, messageChain=messagechain)
    res = requests.request('post', url, json=data_in)
    res = json.loads(res.text)
    if res['code'] == 0:
        return res['messageId']


# 获取数据包，填入mah配置的地址host端口号port和密钥verifyKey以及登录mirai的qq，若已获取会话ID，则可填入会话IDsession
def Creat_data(host='127.0.0.1', port='8080', verifyKey='', qq='', session=''):
    host = str(host)
    port = str(port)
    verifyKey = str(verifyKey)
    qq = str(qq)
    host = host + ':' + port
    data = dict(host=host, Key=verifyKey, qq=qq, session=session)
    return data


# 撤回消息，messageid为消息的id
def Recall_Message(data, messageid):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/recall'
    data_in = dict(sessionKey=session, target=messageid)
    res = requests.request('post', url, json=data_in)
    res = json.loads(res.text)
    return res


# 禁言成员(target为指定群，member为对象qq号，time为禁言时间，单位秒，若不传入member，则默认全体禁言)
# 需要有相关权限
def Mute(data, target, member='0', time=0, ):
    session = data['session']
    host = data['host']
    if member != '0':
        url = 'http://' + host + '/mute'
        data_in = dict(sessionKey=session, target=target, memberId=member, time=time)
        res = requests.request('post', url, json=data_in)
        res = json.loads(res.text)
        return res
    else:
        url = 'http://' + host + '/muteAll'
        data_in = dict(sessionKey=session, target=target)
        res = requests.request('post', url, json=data_in)
        res = json.loads(res.text)
        return res


# 解除禁言(target为指定群，member为对象qq号，若不传入member，则默认解除全体禁言)
# 需要有相关权限
def Unmute(data, target, member='0'):
    session = data['session']
    host = data['host']
    if member != '0':
        url = 'http://' + host + '/unmute'
        data_in = dict(sessionKey=session, target=target, memberId=member)
        res = requests.request('post', url, json=data_in)
        res = json.loads(res.text)
        return res
    else:
        url = 'http://' + host + '/unmuteAll'
        data_in = dict(sessionKey=session, target=target)
        res = requests.request('post', url, json=data_in)
        res = json.loads(res.text)
        return res


# 踢出群成员(target为指定群，member为对象qq号)
# 需要有相关权限
def Kick(data, target, member):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/kick'
    data_in = dict(sessionKey=session, target=target, memberId=member)
    res = requests.request("post", url, json=data_in)
    res = json.loads(res.text)
    return res


# 设置群 target为指定群，config为需设置内容,数据类型为字典dict,或在传参时指定参数名称传入
# 例:Group_Config(data,target,name='ok',announcement='test'……)
# config中的参数名称：name(str)-群名，announcement(str)-群公告，confessTalk(bool)-是否开启坦白说；
# allowMemberInvite(bool)-是否允许群员邀请，autoApprove(bool)-是否开启自动审批入群，anonymousChat(bool)-是否允许匿名聊天
# 需要有相关权限
def Group_Config(data, target, **config):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/groupConfig'
    data_in = dict(sessionKey=session, target=target, config=config)
    res = requests.request('post', url, json=data_in)
    res = json.loads(res.text)
    return res


# 设置群成员资料，target为指定群，memberid为群成员QQ，config为需设置内容,数据类型为字典dict,或在传参时指定参数名称传入
# 例:Member_Info(data,target,memberid，name='ok',specialTitle='test'……)
# config中的参数名称：name(str)-群名片，specialTitle(str)-群头衔
# 需要有相关权限
def Member_Info(data, target, memberid, **config):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/memberInfo'
    data_in = dict(sessionKey=session, target=target, memberId=memberid, info=config)
    res = requests.request('post', url, json=data_in)
    res = json.loads(res.text)
    return res


# 退出群聊，target为指定群
def Quit(data, target):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/quit'
    data_in = dict(sessionKey=session, target=target)
    res = requests.request('post', url, json=data_in)
    res = json.loads(res.text)
    return res


# 取得bot的好友列表，返回值为列表
# 参数名称：id-qq号，nickname-好友昵称，remark-备注
def Get_Friend(data):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/friendList?sessionKey=' + session
    res = requests.request('get', url)
    res = json.loads(res.text)
    List = res['data']
    return List


# 取得bot的群列表，返回值为列表
# 参数名称：id-群号，name-群昵称，permission-权限
def Get_Group(data):
    session = data['session']
    host = data['host']
    url = 'http://' + host + '/groupList?sessionKey=' + session
    res = requests.request('get', url)
    res = json.loads(res.text)
    List = res['data']
    return List


# 取得指定群的设置信息，返回值为字典
# 参数名称：name-群名称，confessTalk-是否开启坦白说，allowMemberInvite-是否允许群员邀请，autoApprove-是否开启自动审批入群，anonymousChat-是否允许匿名聊天
def Get_Groupinfo(data, target):
    session = data['session']
    host = data['host']
    target = str(target)
    url = 'http://' + host + '/groupConfig?sessionKey=' + session + '&target=' + target
    res = requests.request('get', url)
    res = json.loads(res.text)
    return res


# 取得指定群的群成员列表，返回值为列表
# 参数名称：id-qq号，memberName-群名片，specialTitle-群头衔，permission-权限
# 若传入deal=0，则还可返回群成员的joinTimestamp-入群时间戳，lastSpeakTimestamp-最后一次发言时间戳,muteTimeRemaining-禁言剩余时间
def Get_Groupmember(data, target, deal=1):
    if deal != 1 and deal != 0:
        return 0
    session = data['session']
    host = data['host']
    target = str(target)
    url = 'http://' + host + '/memberList?sessionKey=' + session + '&target=' + target
    res = requests.request('get', url)
    res = json.loads(res.text)
    List = res['data']
    for i in List:
        i.pop('group')
        if deal != 0:
            i.pop('joinTimestamp')
            i.pop('lastSpeakTimestamp')
            i.pop('muteTimeRemaining')
    return List


# 取得指定群的群成员资料，返回值为字典
# 参数名称：id-qq号，memberName-群名片，specialTitle-群头衔，permission-权限，muteTimeRemaining-禁言剩余时间
# 若传入deal=0，则还可返回joinTimestamp-入群时间戳，lastSpeakTimestamp-最后一次发言时间戳
def Get_memberinfo(data, target, id, deal=1):
    session = data['session']
    host = data['host']
    target = str(target)
    id = str(id)
    url = 'http://' + host + '/memberInfo?sessionKey=' + session + '&target=' + target + '&memberId=' + id
    res = requests.request('get', url)
    res = json.loads(res.text)
    res.pop('group')
    if deal == 1:
        res.pop('joinTimestamp')
        res.pop('lastSpeakTimestamp')
        return res
    elif deal == 0:
        return res
    else:
        return 0
